﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Windows.Forms;

namespace ArxivatDeDocuments
{
    class PropertiesFileParser
    {

        private string _pathToFile = null;
        Dictionary<string, string> _properties;

        public PropertiesFileParser(String path)
        {
            this._pathToFile = path;            
        }


        public String getPathToFile()
        {
            return _pathToFile;
        }

        public Dictionary<string, string> getProperties()
        { 
            if (_properties == null)
                parseData();

            return _properties;
        }

        private void parseData()
        {
            _properties = new Dictionary<string, string>();
            
            foreach (String row in File.ReadAllLines(_pathToFile,Encoding.Default))
            {
                if (!row.Trim().StartsWith("#") && row.Contains("="))
                {
                    String key = row.Split('=')[0];
                    String value = Decoder(string.Join("=", row.Split('=').Skip(1).ToArray()));

                    _properties.Add(key, value);
                }
            }            
        }

        private static Regex _regex = new Regex(@"\\u(?<Value>[a-zA-Z0-9]{4})", RegexOptions.Compiled);
        public string Decoder(string value)
        {
            return _regex.Replace(value, converter);
        }

        
        private string converter(Match match)
        {
            return ((char)int.Parse(match.Groups["Value"].Value, NumberStyles.HexNumber)).ToString();
        }

        private static char[] HEX = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        public static string escapeValue(string s)
        {
            StringBuilder buf = new StringBuilder();
            bool first = true;

            foreach (char c in s)
            {
                //  Handle value starting with whitespace.
                if (first)
                {
                    first = false;
                    if (c == ' ')
                    {
                        buf.Append('\\').Append(' ');
                        continue;
                    }
                    else if (c == '\t')    //  =09 U+0009  HORIZONTAL TABULATION   \t
                    {
                        buf.Append('\\').Append('t');
                        continue;
                    }
                }

                switch (c)
                {
                    case '\t':  //  =09 U+0009  HORIZONTAL TABULATION   \t
                        buf.Append('\t');  //OK after first position.
                        break;
                    case '\n':  //  =0A U+000A  LINE FEED               \n
                        buf.Append('\\').Append('n');
                        break;
                    case '\f':  //  =0C U+000C  FORM FEED               \f
                        buf.Append('\\').Append('f');
                        break;
                    case '\r':  //  =0D U+000D  CARRIAGE RETURN         \r
                        buf.Append('\\').Append('r');
                        break;
                    case '\\':  //  92: '\'
                        buf.Append('\\').Append(c);
                        break;

                    default:
                        if (c > 31 && c < 127)
                        {
                            buf.Append(c);
                        }
                        else
                        {
                            buf.Append('\\').Append('u');
                            buf.Append(HEX[(c >> 12) & 0xF]);
                            buf.Append(HEX[(c >> 8) & 0xF]);
                            buf.Append(HEX[(c >> 4) & 0xF]);
                            buf.Append(HEX[c & 0xF]);
                        }
                        break;
                }
            }

            return buf.ToString();
        }

    
    }
}
